﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using log4net;
using System.Reflection;

namespace DataRecv.tools
{
    public class picCompress
    {
        private static ILog loger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// 图片按设定的阈值进行压缩，转换成功，则保存转换后的图片到本地
        /// </summary>
        /// <param name="inPath">源图片的绝对地址</param>
        /// <param name="outPath">转换后图片的绝对地址</param>
        /// <param name="intLimit">设定的阈值，单位为字节数，例如为(500KB*1024)Bytes</param>
        /// <returns>是否转换成功，转换成功时保存图片</returns>
        public static bool picFilePressLimit(string inPath, string outPath, int intLimit)
        {
            if (!Directory.Exists(outPath.Remove(outPath.LastIndexOf("\\"))))
            {
                try
                {
                    Directory.CreateDirectory(outPath);
                }
                catch (Exception Ex) { loger.Error(Ex); }
            }

            int len = intLimit * 1024;
            int quality = 100;

            byte[] fileBytes = File.ReadAllBytes(inPath);
            byte[] outBytes = null;

            while ( (picBytesPress(fileBytes,out outBytes,quality)) && (outBytes != null) && (outBytes.Length >len)) 
	        {
                if (quality > 0) quality -= 5;
	        }

            try
            {
                File.WriteAllBytes(outPath, outBytes);
            }
            catch (Exception ex)
            {
                loger.Info("picPressLimit" + ex.Message);
                return false;
            }

            return true;

        }

        /// <summary>
        /// 图片按设定的阈值进行压缩，返回字节
        /// </summary>
        /// <param name="inBytes">源图片的字节数组</param>
        /// <param name="outBytes">转换后图片的字节数组</param>
        /// <param name="intLimit">设定的阈值，单位为字节数，例如为(500KB*1024)Bytes</param>
        /// <returns>图片的字节数组</returns>
        public static bool picBytesPressLimit(byte[] inBytes, out byte[] outBytes, int intLimit)
        {
            int len = intLimit;
            int quality = 100;

            try
            {
                while ((picBytesPress(inBytes, out outBytes, quality)) && (outBytes != null) && (outBytes.Length > len))
                {
                    if (quality > 0) quality -= 5;
                }
            }
            catch (Exception ex)
            {
                loger.Info("picPressLimit" + ex.Message);
                outBytes = null;
                return false;
            }

            return true;

        }

        /// <summary>
        /// 压缩处理
        /// </summary>
        /// <param name="sFile">源文件路径</param>
        /// <param name="outPath">输出路径</param>
        /// <param name="quality">压缩的比例1-100 </param>
        /// <returns>压缩是否成功</returns>
        public static bool picFilePress(string inPath, string outPath, int quality)
        {
            
            string outDir = outPath.Substring(0, outPath.LastIndexOf('\\'));

            if (!Directory.Exists(outDir))
            {
                try
                {
                    Directory.CreateDirectory(outDir);
                }
                catch (Exception Ex) { loger.Error(Ex); }
            }

            Image image = Image.FromFile(inPath);
            //压缩时图像重新编码的参数
            EncoderParameters EP = new EncoderParameters();
            EP.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);

            try
            {
                ImageCodecInfo[] ICIArray = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo ICIJpeg = null;
                for (int x = 0; x < ICIArray.Length; x++)
                {
                    if (ICIArray[x].FormatDescription.Equals("JPEG"))
                    {
                        ICIJpeg = ICIArray[x];
                        break;
                    }
                }
                if (ICIJpeg != null)
                {
                    image.Save(outPath, ICIJpeg, EP);
                }
                else
                {
                    image.Save(outPath, image.RawFormat);
                }
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                if (image != null)
                {
                    image.Dispose();
                }

            }

        }

        /// <summary>
        /// 压缩处理
        /// </summary>
        /// <param name="sFile">源文件路径</param>
        /// <param name="outPath">输出路径</param>
        /// <param name="quality">压缩的比例1-100 </param>
        /// <returns>压缩是否成功</returns>
        public static bool picBytesPress(byte[] inBytes, out byte[] outBytes, int quality)
        {
            MemoryStream ms_in = null;
            MemoryStream ms_out = null;
            ms_in = new MemoryStream(inBytes);
            ms_out = new MemoryStream();

            Image image = Image.FromStream(ms_in);
            //压缩时图像重新编码的参数
            EncoderParameters EP = new EncoderParameters();
            EP.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);

            try
            {
                ImageCodecInfo[] ICIArray = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo ICIJpeg = null;
                for (int x = 0; x < ICIArray.Length; x++)
                {
                    if (ICIArray[x].FormatDescription.Equals("JPEG"))
                    {
                        ICIJpeg = ICIArray[x];
                        break;
                    }
                }

                if (ICIJpeg != null)
                {
                    image.Save(ms_out, ICIJpeg, EP);
                    outBytes = ms_out.ToArray();
                }
                else
                {
                    image.Save(ms_out, image.RawFormat);
                    outBytes = ms_out.ToArray();
                }
                return true;
            }
            catch
            {
                outBytes = null;
                return true;
            }
            finally
            {
                if (image != null)
                {
                    image.Dispose();
                }

                if (ms_in != null)
                {
                    ms_in.Close();
                    ms_in.Dispose();
                }

                if (ms_out != null)
                {
                    ms_out.Close();
                    ms_out.Dispose();
                }
                GC.Collect();
            }
        }

        private string GetPic(byte[] picbyte, int qty)
        {
            try
            {
                if ((picbyte.Length / 1024) > 300)//图片大于300k进行图片压缩
                //while ((picbyte.Length / 1024) > 300)
                {
                    MemoryStream st = new MemoryStream(picbyte);
                    Bitmap bitmap = new Bitmap(st);

                    EncoderParameters ps = new EncoderParameters(1);
                    EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qty);
                    MemoryStream memoryStream = new MemoryStream();
                    try
                    {
                        ps.Param[0] = p;
                        bitmap.Save(memoryStream, GetCodecInfo("image/jpeg"), ps);
                        picbyte = memoryStream.ToArray(); //压缩后小于300k的图片
                    }
                    catch (Exception ex)
                    {
                        loger.Error(ex);
                    }
                    finally
                    {
                        memoryStream.Close();
                        st.Close();
                        bitmap.Dispose();
                        ps.Dispose();
                        p.Dispose();
                    }
                }
                //如欲开启web相关内容，取消注释
                //return System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(picbyte), Encoding.UTF8);
                return string.Empty;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 保存JPG时用
        /// </summary>
        /// <param name="mimeType"></param>
        /// <returns>得到指定mimeType的ImageCodecInfo</returns>
        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.MimeType == mimeType) return ici;
            }
            return null;
        }
        
    }
}
